package com.yicheng.statistics.actor.analysis

import java.util.Date
import java.util.concurrent.CountDownLatch

import org.joda.time.DateTime

import com.yicheng.statistics.actor.SaveHtaData
import com.yicheng.statistics.common.TimeUtils
import com.yicheng.statistics.repo.RTAModel.BatteryAlarm
import com.yicheng.statistics.repo.model.Data.AlarmInfo

import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.ActorRef
import akka.actor.Props
import com.yicheng.statistics.repo.cassandra.AlarmInfoDb
import scala.util.Failure
import scala.util.Success

/**
 * 电池报警统计
 * 从报警表里取出电池报警的数据，
 * 如果达到预报警速度门限开始记录等到达到时间门限就统计一条预报警信息，
 * 如果达到报警速度门限开始记录等到达到时间门限就统计一条报警信息
 */
class BatteryAlarmActor extends Actor with ActorLogging{
  
  val saveHtaDataActor:ActorRef = context.child("saveHtaData").
    getOrElse(context.actorOf(Props[SaveHtaData], "saveHtaData"))
  
  import scala.concurrent.ExecutionContext.Implicits.global
  def receive: Receive = {
    case (deviceId:String, deviceType:Int, analyseGroupId:Long) =>
      log.info("电池报警统计 deviceId "+deviceId)
      var alarmState:AlarmState = AlarmState(false, None, None, None, None, None, None, None, None, None, None)
      val alarmInfos: List[AlarmInfo] = List()
      
      val cql = new CountDownLatch(24)
      (0 to 23) foreach {//0点开始到23点(0 to 23).map(//0点开始到23点
        t => {

          val time:(DateTime, DateTime) = TimeUtils.getStartEndTimeByHour(t, 1)
          
          AlarmInfoDb.list(deviceType, deviceId, time._1.toDate(), time._2.toDate()) onComplete {
            case Success(result) => 
              result.filter(ai => ai.alarm_code.get >= 20000 && ai.alarm_code.get <30000).foreach {//过滤电池报警的信息
                ai => alarmInfos :+ ai
              }
              cql.countDown()
            case Failure(error) =>
              log.error(error.getMessage)
            
          }
          
        }}
      
      cql.await()
      
      alarmInfos.sortWith((a1:AlarmInfo, a2:AlarmInfo) => a1.alarm_time.getTime < a2.alarm_time.getTime) foreach {//过滤电池报警的信息
        ai =>
          log.info("alarminfo content is "+ai)
          val vehicleData = ai.alarm_detail.get.alarmVehicle.get.vehicleData
          val alarmdata = vehicleData.alarmData
          val allData = vehicleData.overallData
          val posData = vehicleData.posData
          
          if(!alarmState.start){
            alarmState = alarmState.copy(
                start = true, 
                startTime = Some(ai.alarm_time), 
                startLat = posData.get.latitude, 
                startLon = posData.get.longitude, 
                startMileage = Some(allData.get.currentMileage),
                alarmType = ai.alarm_type, 
                alarmLevel = ai.alarm_level)
          }else{
            if( alarmState.alarmType != ai.alarm_type ){
              val batteryAlarm = BatteryAlarm(
                  deviceType,
                  deviceId,
                  alarmState.startTime,
                  alarmState.endTime,
                  alarmState.startLon,
                  alarmState.startLat,
                  alarmState.endLon,
                  alarmState.endLat,
                  alarmState.startMileage,
                  alarmState.endMileage,
                  DateTime.now.toDate(),
                  alarmState.alarmType.get,
                  None,
                  None,
                  alarmState.alarmLevel,
                  None,
                  None,
                  None
                  )
              alarmState = alarmState.copy(
                  start = true, 
                  startTime = Some(ai.alarm_time), 
                  startLat = posData.get.latitude, 
                  startLon = posData.get.longitude, 
                  startMileage = Some(allData.get.currentMileage),
                  alarmType = ai.alarm_type, 
                  alarmLevel = ai.alarm_level)
              
              saveHtaDataActor ! batteryAlarm
            }
            else{
              alarmState = alarmState.copy(
                  endTime = Some(ai.alarm_time), 
                  endLat = posData.get.latitude, 
                  endLon = posData.get.longitude, 
                  endMileage = Some(allData.get.currentMileage))
            }
            
          }
      }
    case _ => log.info("BatteryAlarm")
  }
}

case class AlarmState(
    start:Boolean,
    startTime:Option[Date],
    startLat:Option[Double],
    startLon:Option[Double],
    endTime:Option[Date],
    endLat:Option[Double],
    endLon:Option[Double],
    startMileage:Option[Int],
    endMileage:Option[Int],
    alarmType:Option[Int],
    alarmLevel:Option[Int]
    )